/**
 * 获取Dom高度
 * @author 木人心
 * @version 1.1.1
 */
import { Directive } from 'vue'

type MapValueType = { cssKey?: string, callback?: {(height: number)} }
const propertyMap = new Map<HTMLElement, MapValueType>()
const observer = new ResizeObserver((entries) => {
  for (let i = 0, len = entries.length; i < len; i++) {
    const el = entries[i].target as HTMLElement
    const option = propertyMap.get(el)
    const height = el.getBoundingClientRect().height
    el.style.setProperty(option.cssKey, height + 'px')
    option.callback && option.callback(height)
  }
})

/**
 * 指令
 * 使用方法：v-ref-height="varName"
 * @param varName string | { cssKey?: string, callback?: {(height: number)} }
 */
const RefHeight: Directive = {
  mounted (el, binding) {
    const option: MapValueType = { cssKey: '--ref-height' }
    if (typeof binding.value === 'string') {
      option.cssKey = '--' + (binding.value || 'ref-height')
    } else {
      const _binding: MapValueType = binding.value
      if (_binding) {
        if (_binding.cssKey) option.cssKey = _binding.cssKey
        if (_binding.callback) option.callback = _binding.callback
      }
    }
    propertyMap.set(el, option)
    observer.observe(el)
  },
  unmounted (el) {
    observer.unobserve(el)
    propertyMap.delete(el)
  }
}

export default RefHeight
